home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -seriously_amiga- / shareware / programming / c / amivogl-mdev / src / amiga.c next >
C/C++ Source or Header  |  1998-01-12  |  38KB  |  1,312 lines

  1. /*
  2.  * Vogle driver for the Amiga
  3.  *
  4.  * Written By: Dr. Charles E. Campbell, Jr.
  5.  * Version   : 1.00
  6.  * Date      : September 28, 1993
  7.  *
  8.  */
  9. #include <stdio.h>
  10. // #include <fcntl.h>
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14.  
  15. #include <functions.h>
  16. #include <exec/types.h>
  17. #include <intuition/intuition.h>
  18. #include <libraries/dos.h>
  19. #include <graphics/rastport.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/text.h>
  22. #include <exec/memory.h>
  23. #include <devices/inputevent.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/console_protos.h>
  27.  
  28. #include "vogl.h"
  29.  
  30. #define INTUITION_REV    ((unsigned long) 33L)
  31. #define GRAPICS_REV        ((unsigned long) 33L)
  32.  
  33. /* --------------------------------------------------------------------------
  34.  * Definitions Section:
  35.  */
  36. #define SNGLBUFMODE    0    /* default scrbufmode value                    */
  37. #define DBLBUFMODE    1    /* scrbufmode value                            */
  38. #define RAWKEYBUF    128    /* initial size of rawkey buffer conversion    */
  39. #define KEYBUF        256    /* max size of keybuffer to be read            */
  40.  
  41. #define FONTSEP        ';'
  42. #define MAXVRTX        200
  43. #define MAXSTRING    1024
  44.  
  45. #ifdef SASC
  46. #define USESVMODE
  47. #endif
  48.  
  49. #ifdef AZTEC_C
  50. #define MEMTYPE    (MEMF_ANY|MEMF_CLEAR)
  51. #else
  52. #define MEMTYPE    (MEMF_ANY|MEMF_CLEAR)
  53. #endif
  54.  
  55. /* head_link: handles the generation of head-linked lists.  Note that 
  56.  *   each structure is assumed to have the member "nxt".
  57.  *   The new member becomes "head" - ie. oldest is last in the linked list,
  58.  *   the newest is first.
  59.  */
  60. #define head_link(structure,head,fail_msg) {         \
  61.     structure *newstr;                               \
  62.     newstr= (structure *) malloc(sizeof(structure)); \
  63.     if(!newstr) printf("***out of memory*** <%s>\n",fail_msg);   \
  64.     newstr->nxt= head;                               \
  65.     head    = newstr;                                \
  66.     }
  67.  
  68. /* stralloc: allocates new memory for and copies a string into the new mem */
  69. #define stralloc(ptr,string,fail_msg) {                             \
  70.     ptr= (char *) calloc((size_t) strlen(string) + 1,sizeof(char)); \
  71.     if(!ptr) printf("***out of memory*** <%s>\n",fail_msg);                  \
  72.     strcpy(ptr,string);                                             \
  73.     }
  74.  
  75. /* --------------------------------------------------------------------------
  76.  * Typedefs:
  77.  */
  78. typedef struct FontList_str FontList;
  79.  
  80. /* --------------------------------------------------------------------------
  81.  * Data Structures:
  82.  */
  83. struct FontList_str {
  84.     char            *fontspec;
  85.     struct TextFont *textfont;
  86.     FontList        *nxt;
  87.     };
  88.  
  89. /* --------------------------------------------------------------------------
  90.  * Extern Data:
  91.  */
  92. #ifdef AZTEC_C
  93. extern int Enable_Abort;
  94. #else
  95. void __regargs __checkabort (void);
  96. #endif
  97.  
  98. /* --------------------------------------------------------------------------
  99.  * Local Data:
  100.  */
  101. WORD                 *voglareaBuffer= NULL;
  102. struct BitMap        *voglback      = NULL;
  103. struct BitMap        *voglfront     = NULL;
  104. struct DiskFontBase  *DiskfontBase  = NULL;
  105. struct GfxBase       *GfxBase       = NULL;
  106. struct IntuiText     *voglitext     = NULL;
  107. struct IntuitionBase *IntuitionBase = NULL;
  108. struct IOStdReq      *vogl_cd_ioreq = NULL;
  109. struct Library       *ConsoleDevice = NULL;
  110. struct RastPort      *voglrastport  = NULL;
  111. struct Screen        *voglscreen    = NULL;
  112. struct TextAttr      *vogltextattr  = NULL;
  113. struct TmpRas        *vogltmpras    = NULL;
  114. struct Window        *voglwindow    = NULL;
  115.  
  116. static char               useborder       = 0;
  117. static char               scrbufmode      = SNGLBUFMODE;
  118. static char              *rawkeybuf       = NULL;
  119. static int                grfxmode        = 0;
  120. static int                currcolor       = 0;
  121. static UBYTE             *voglstring      = NULL;
  122. static UWORD              scrdepth        = 4;
  123. static UWORD              scrwidth        = 0;
  124. static UWORD              scrheight       = 0;
  125. static UWORD              voglscrbordleft = 0;
  126. static UWORD              voglscrbordright= 0;
  127. static UWORD              voglscrbordtop  = 0;
  128. static UWORD              voglscrbordbttm = 0;
  129. static USHORT             screenviewmode  = HIRES|LACE;
  130. static LONG               qtyrawkeybuf    = 0L;
  131. static FontList          *fontlisthd      = NULL;
  132. static struct InputEvent *voglievent      = NULL;
  133. static PLANEPTR          voglplaneptr     = NULL;
  134.  
  135. /* voglkeybuf
  136.  *   |uuuddddddduuuuu|    u=unused  d=data
  137.  *      ^       ^
  138.  *   ikeybgn    ikeyend   (always point to unused)
  139.  */
  140. static char     voglkeybuf[KEYBUF];
  141. static unsigned ikeyend= 0;            /* points just-past chars in voglkeybuf        */
  142. static unsigned ikeybgn= KEYBUF-1;    /* points just-before chars in voglkeybuf    */
  143.  
  144.  
  145. /* --------------------------------------------------------------------------
  146.  * Local Prototypes:
  147.  */
  148. static int AMIGA_config(char *);                             /* amiga.c         */
  149. static int AMIGA_init(void);                                  /* amiga.c         */
  150. static struct BitMap *makeBitMap(void);                /* amiga.c         */
  151. static int freeBitMap(struct BitMap *);                      /* amiga.c         */
  152. static int AMIGA_exit(void);                                  /* amiga.c         */
  153. static int AMIGA_draw( int, int);                            /* amiga.c         */
  154. static int AMIGA_getkey(void);                                /* amiga.c         */
  155. static int AMIGA_checkkey(void);                              /* amiga.c         */
  156. static int AMIGA_locator( int *, int *);                      /* amiga.c         */
  157. static int AMIGA_clear(void);                                /* amiga.c         */
  158. static int AMIGA_color(int);                                 /* amiga.c         */
  159. static int AMIGA_mapcolor( int, int, int, int);              /* amiga.c         */
  160. static int AMIGA_font(char *);                                /* amiga.c         */
  161. static int AMIGA_char(char);                                 /* amiga.c         */
  162. static int AMIGA_string(char *);                             /* amiga.c         */
  163. static int AMIGA_fill( int, int[], int[]);                   /* amiga.c         */
  164. static int AMIGA_backbuffer(void);                            /* amiga.c         */
  165. static int AMIGA_swapbuffer(void);                            /* amiga.c         */
  166. static int AMIGA_frontbuffer(void);                          /* amiga.c         */
  167. void _AMIGA_devcpy(void);                              /* amiga.c         */
  168.  
  169.  
  170. /* --------------------------------------------------------------------------
  171.  * Device Entry
  172.  *    fontname;height[;{BEIPU}]
  173.  *   B == bold
  174.  *   E == extended
  175.  *   I == italic
  176.  *   P == plain (default)
  177.  *   U == underlined
  178.  */
  179. static DevEntry amigadev = {
  180.     "AMIGA",                /* name of device                                */
  181.     "topaz;9;P",            /* name of small "hardware" font                */
  182.     "topaz;11;P",        /* name of large "hardware" font                */
  183.     AMIGA_backbuffer,    /* initializes double buffering                    */
  184.     AMIGA_char,            /* prints a "hardware" character                */
  185.     AMIGA_checkkey,        /* check if keyboard key hit, return it            */
  186.     AMIGA_clear,            /* clears viewport to background                */
  187.     AMIGA_color,            /* change current color index                    */
  188.     AMIGA_draw,            /* draws line from current to (x,y)                */
  189.     AMIGA_exit,            /* cleans up and allows vogle to exit            */
  190.     AMIGA_fill,            /* does filled polygons                            */
  191.     AMIGA_font,            /* sets up a hardware font                        */
  192.     AMIGA_frontbuffer,    /* switches drawing into front buffer            */
  193.     AMIGA_getkey,        /* gets a char of input                            */
  194.     AMIGA_init,            /* enables graphics                                */
  195.     AMIGA_locator,        /* finds mouse position in vogle device coords    */
  196.     AMIGA_mapcolor,        /* changes color at index to given rgb value    */
  197.     AMIGA_string,        /* prints a string of hardware text                */
  198.     AMIGA_swapbuffer};    /* swaps front and back buffers                    */
  199.  
  200. /* ==========================================================================
  201.  * Source Code:
  202.  */
  203.  
  204. /* AMIGA_config: This function modifies what AMIGA_init does.  It allows the
  205.  * user to control the type of screen and bitmaps used.  Note that one may
  206.  * use extra half-brite mode, too.  I put in ham mode since I expect to
  207.  * attempt to do some shading someday.
  208.  *
  209.  * The AMIGA_init sets up a gimmezerozero window using a custom Screen and
  210.  * BitMap.
  211.  *
  212.  * The config string may include:
  213.  *      b : use border&title on window
  214.  *        d : double buffer mode
  215.  *        e : extra halfbrite mode
  216.  *        h : ham graphics mode
  217.  *      s : single buffer mode
  218.  *        1-5 : 1,2,3, 4, 5 bit planes (2,4,8,16,64 colors, respectively)
  219.  *
  220.  * Screen height will be max and interlaced.
  221.  * Screen width  will be 640 for 1-4 bit planes and 320 otherwise
  222.  */
  223. static int AMIGA_config(char *config)
  224. {
  225. // Enable_Abort=0;
  226.  
  227. for(; *config; ++config) switch(*config) {
  228.  
  229. case 'b':    /* use border on window */
  230.     useborder= 1;
  231.     break;
  232.  
  233. case 'd':    /* double buffer mode    */
  234.     scrbufmode= DBLBUFMODE;
  235.     break;
  236.  
  237. case 'e':    /* extra halfbrite mode    */
  238.     screenviewmode= LACE|EXTRA_HALFBRITE;
  239.     scrdepth     = 6;
  240.     break;
  241.  
  242. case 'h':    /* ham mode                */
  243.     screenviewmode= LACE|HAM;
  244.     scrdepth     = 6;
  245.     break;
  246.  
  247. case 's':    /* single buffer mode */
  248.     scrbufmode= SNGLBUFMODE;
  249.     break;
  250.  
  251. case '1':    /* one bit plane        */
  252.     screenviewmode= LACE|HIRES;
  253.     scrdepth     = 1;
  254.     break;
  255.  
  256. case '2':    /* two bit planes        */
  257.     screenviewmode= LACE|HIRES;
  258.     scrdepth     = 2;
  259.     break;
  260.  
  261. case '3':    /* three bit planes        */
  262.     screenviewmode= LACE|HIRES;
  263.     scrdepth     = 3;
  264.     break;
  265.  
  266. case '4':    /* four bit planes        */
  267.     screenviewmode= LACE|HIRES;
  268.     scrdepth     = 4;
  269.     break;
  270.  
  271. case '5':
  272.     screenviewmode= LACE;
  273.     scrdepth     = 5;
  274.     break;
  275.  
  276. default:
  277.     screenviewmode= LACE|HIRES;
  278.     scrdepth     = 4;
  279.     printf("***warning*** AMIGA_config: bad config<%s> string\n",config);
  280.     break;
  281.     }
  282.  
  283.     return(0);
  284. }
  285.  
  286. /* -------------------------------------------------------------------------- */
  287.  
  288. /* AMIGA_init: initialises drawing canvas to occupy current window
  289.  *  a routine which enables graphics on the device, sets the default
  290.  *  colour map, and sets vdevice.maxS{x,y} and vdevice.minS{x,y} to the
  291.  *  window size in pixels.
  292.  */
  293. static int AMIGA_init(void)
  294. {
  295. int               gx,gy;            /* getprefposandsize x,y    */
  296. int               gxs,gys;            /* getprefposandsize xs,ys    */
  297. struct Screen    *wbscreen=NULL;
  298. struct NewScreen *newscreen=NULL;
  299. struct NewWindow *newwindow=NULL;
  300.  
  301. // Enable_Abort=0;
  302.  
  303. /* don't let user initialize twice (or more!) */
  304. if(IntuitionBase) {
  305.     printf("***warning*** AMIGA_init: attempt to initialize twice!\n");
  306.     return 0;
  307.     }
  308.  
  309. /* allocate some memory needed for the ConsoleDevice */
  310. vogl_cd_ioreq= (struct IOStdReq *)
  311.   AllocMem(sizeof(struct IOStdReq),MEMTYPE);
  312. if(!vogl_cd_ioreq) {
  313.     AMIGA_exit();
  314.     printf("***warning*** unable to allocate a IOStdReq\n");
  315.     goto initproblem;
  316.     }
  317.  
  318. /* open Intuition */
  319. IntuitionBase= (struct IntuitionBase *)
  320.   OpenLibrary((UBYTE *) "intuition.library",INTUITION_REV);
  321. if(IntuitionBase == NULL) {
  322.     AMIGA_exit();
  323.     printf("***warning*** unable to open Intuition Library\n");
  324.     goto initproblem;
  325.     }
  326.  
  327. /* open Graphics */
  328. GfxBase= (struct GfxBase *)
  329.   OpenLibrary((UBYTE *) "graphics.library",INTUITION_REV);
  330. if(GfxBase == NULL) {
  331.     AMIGA_exit();
  332.     printf("***warning*** unable to open Graphics Library\n");
  333.     goto initproblem;
  334.     }
  335.  
  336. /* open DiskFont */
  337. DiskfontBase= (struct DiskFontBase *)
  338.   OpenLibrary((UBYTE *) "diskfont.library",0L);
  339. if(DiskfontBase == NULL) {
  340.     AMIGA_exit();
  341.     printf("***warning*** unable to open DiskFont library\n");
  342.     goto initproblem;
  343.     }
  344.  
  345. /* open ConsoleDevice */
  346. if(OpenDevice((UBYTE *) "console.device",-1L,(struct IORequest *) vogl_cd_ioreq,0L) != 0) {
  347.     AMIGA_exit();
  348.     printf("***warning*** unable to open DiskFont library\n");
  349.     goto initproblem;
  350.     }
  351. ConsoleDevice= (struct Library *) vogl_cd_ioreq->io_Device;
  352.  
  353. /* determine screen width and height from screenviewmode */
  354.  
  355. #ifdef USESVMODE
  356.  
  357. /* this code uses screenviewmode by itself, setting up standard
  358.  * height and width
  359.  */
  360. scrwidth= 640;
  361. if( (screenviewmode & HAM)   ||
  362.    !(screenviewmode & HIRES) ||
  363.     (screenviewmode & EXTRA_HALFBRITE)) scrwidth= 320;
  364. scrheight= 256;
  365. if(screenviewmode & LACE) scrheight= 400;
  366.  
  367. #else
  368.  
  369. /* lock WorkBench screen and query it for its dimensions */
  370. wbscreen= LockPubScreen((UBYTE *) "Workbench");
  371. if(wbscreen) {
  372.     scrheight= wbscreen->Height;
  373.     scrwidth = wbscreen->Width;
  374.  
  375.     
  376.     if     ( (wbscreen->ViewPort.Modes & LACE)  && !(screenviewmode & LACE))  scrheight/= 2;
  377.     else if(!(wbscreen->ViewPort.Modes & LACE)  &&  (screenviewmode & LACE))  scrheight*= 2;
  378.     if     ( (wbscreen->ViewPort.Modes & HIRES) && !(screenviewmode & HIRES)) scrwidth /= 2;
  379.     else if(!(wbscreen->ViewPort.Modes & HIRES) &&  (screenviewmode & HIRES)) scrwidth *= 2;
  380.  
  381.     voglscrbordtop  = wbscreen->WBorTop + wbscreen->Font->ta_YSize + 1;
  382.     UnlockPubScreen(NULL,wbscreen);
  383.     }
  384. else voglscrbordtop= 0;
  385. #endif
  386.  
  387. /* allocate a NewScreen in CHIP memory */
  388. newscreen= AllocMem(sizeof(struct NewScreen),MEMTYPE);
  389. if(!newscreen) {
  390.     AMIGA_exit();
  391.     printf("***warning*** unable to allocate a NewScreen\n");
  392.     goto initproblem;
  393.     }
  394.  
  395. /* set up both front and back BitMaps.  Note that Vogl signals
  396.  * use of double buffering after this function is called
  397.  * (the doublebuffer() function calls AMIGA_backbuffer
  398.  * which begins backbuffering)
  399.  */
  400. voglfront= makeBitMap();
  401. if(!voglfront) {
  402.     AMIGA_exit();
  403.     printf("***warning*** unable to allocate front BitMap\n");
  404.     goto initproblem;
  405.     }
  406.  
  407. voglback= makeBitMap();
  408. if(!voglback) {
  409.     AMIGA_exit();
  410.     printf("***warning*** unable to allocate back BitMap\n");
  411.     goto initproblem;
  412.     }
  413.  
  414. /* initialize NewScreen */
  415. newscreen->LeftEdge    = 0;
  416. newscreen->TopEdge     = 0;
  417. newscreen->Width       = scrwidth;
  418. newscreen->Height      = scrheight;
  419. newscreen->Depth       = scrdepth;
  420. newscreen->DetailPen   = 1;
  421. newscreen->BlockPen    = 0;
  422. newscreen->ViewModes   = screenviewmode;
  423. newscreen->Type        = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET;
  424. newscreen->Font        = (struct TextAttr *) NULL;
  425. newscreen->DefaultTitle= (UBYTE *) NULL;
  426. newscreen->CustomBitMap= voglfront;
  427.  
  428. voglscreen             = OpenScreen(newscreen);
  429. FreeMem(newscreen,sizeof(struct NewScreen));
  430.  
  431. if(!voglscreen) {
  432.     AMIGA_exit();
  433.     printf("***warning*** unable to open a Screen\n");
  434.     goto initproblem;
  435.     }
  436.  
  437. /* allocate and initialize a window */
  438. newwindow= AllocMem((LONG) sizeof(struct NewWindow),MEMTYPE);
  439. if(!newwindow) {
  440.     AMIGA_exit();
  441.     printf("***warning*** unable to allocate a NewWindow\n");
  442.     goto initproblem;
  443.     }
  444.  
  445. /* get user-specified initial window position and size
  446.  *  The user specifies these parameters with
  447.  *
  448.  *  prefposition(long x,long y)
  449.  *  prefsize(long xs,long ys)
  450.  *
  451.  * *prior* to calling winopen() or ginit().
  452.  * Vogl initializes gx, gy, gxs, gys to -1
  453.  */
  454. getprefposandsize(&gx,&gy,&gxs,&gys);
  455. if(gx  < 0 || scrwidth  < gx)  gx = 0;
  456. if(gy  < 0 || scrheight < gy)  gy = 0;
  457. if(gxs < 0 || scrwidth  < gxs) gxs= scrwidth;
  458. if(gys < 0 || scrheight < gys) gys= scrheight;
  459.  
  460. /* the amiga driver's standard window */
  461. newwindow->LeftEdge   = (SHORT) gx;
  462. newwindow->TopEdge    = (SHORT) gy;
  463. newwindow->Width      = (SHORT) gxs;
  464. newwindow->Height     = (SHORT) gys;
  465. newwindow->DetailPen  = (UBYTE) -1;
  466. newwindow->BlockPen   = (UBYTE) -1;
  467. newwindow->IDCMPFlags = (ULONG) IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
  468. newwindow->Flags      = REPORTMOUSE | ACTIVATE | RMBTRAP;
  469. newwindow->FirstGadget= (struct Gadget *) NULL;
  470. newwindow->CheckMark  = (struct Image *) NULL;
  471. newwindow->Title      = (UBYTE *) NULL;
  472. newwindow->Screen     = voglscreen;
  473. newwindow->BitMap     = voglfront;
  474. newwindow->MinWidth   =  0;
  475. newwindow->MinHeight  =  0;
  476. newwindow->MaxHeight  = ~0;
  477. newwindow->MaxWidth   = ~0;
  478. newwindow->Type       = CUSTOMSCREEN;
  479.  
  480. /* configuration modifications */
  481. if(!useborder) newwindow->Flags|= BORDERLESS;
  482. else {
  483.     int Yfont;
  484.     if(vdevice.wintitle && vdevice.wintitle[0]) {
  485.         newwindow->Title= (UBYTE *) vdevice.wintitle;
  486.         }
  487.     Yfont             = voglscreen->Font? voglscreen->Font->ta_YSize : 0;
  488.     voglscrbordtop    = voglscreen->WBorTop + Yfont + 1;
  489.     voglscrbordbttm   = voglscreen->WBorBottom;
  490.     voglscrbordleft   = voglscreen->WBorLeft;
  491.     voglscrbordright  = voglscreen->WBorRight;
  492.     }
  493.  
  494. /* open the window */
  495. voglwindow= OpenWindow(newwindow);
  496. FreeMem(newwindow,sizeof(struct NewWindow));
  497. if(!voglwindow) {
  498.     AMIGA_exit();
  499.     printf("***warning*** unable to allocate a NewWindow\n");
  500.     goto initproblem;
  501.     }
  502.  
  503. /* set voglrastport up */
  504. voglrastport               = &voglscreen->RastPort;
  505. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap=
  506.   (scrbufmode == DBLBUFMODE)? voglback : voglfront;
  507.  
  508. /* initialize areaBuffer (5 bytes, not words, per vertex) */
  509. voglareaBuffer= (WORD *) AllocMem((LONG) 5*MAXVRTX,MEMTYPE);
  510. if(!voglareaBuffer) {
  511.     AMIGA_exit();
  512.     printf("***warning*** unable to initialize areaBuffer for %d vertices\n",MAXVRTX);
  513.     goto initproblem;
  514.     }
  515.  
  516. voglrastport->AreaInfo= (struct AreaInfo *)
  517.   AllocMem((LONG) sizeof(struct AreaInfo),MEMTYPE);
  518. if(!voglrastport->AreaInfo) {
  519.     AMIGA_exit();
  520.     printf("***warning*** unable to initialize areaInfo\n");
  521.     goto initproblem;
  522.     }
  523. InitArea(voglrastport->AreaInfo,voglareaBuffer,MAXVRTX);
  524.  
  525. /* initialize a TmpRas */
  526. vogltmpras= (struct TmpRas *)
  527.   AllocMem((LONG) sizeof(struct TmpRas),MEMTYPE);
  528. if(!vogltmpras) {
  529.     AMIGA_exit();
  530.     printf("***warning*** unable to allocate a TmpRas\n");
  531.     goto initproblem;
  532.     }
  533.  
  534. voglplaneptr= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  535. if(voglplaneptr) {
  536.     voglrastport->TmpRas= (struct TmpRas *)
  537.       InitTmpRas(vogltmpras,voglplaneptr,RASSIZE(scrwidth,scrheight));
  538.     }
  539. else {
  540.     AMIGA_exit();
  541.     printf("***warning*** unable to allocate a %dx%d raster for TmpRas\n",
  542.       scrwidth,scrheight);
  543.     goto initproblem;
  544.     }
  545.  
  546.  
  547. /* don't outline area fills with the OPen (outline color pen) */
  548. BNDRYOFF(voglrastport);
  549.  
  550. /* set up strings and fonts */
  551. voglitext   = (struct IntuiText *) AllocMem((LONG) sizeof(struct IntuiText),MEMTYPE);
  552. voglstring  = (UBYTE *)            AllocMem((LONG) MAXSTRING*sizeof(UBYTE),MEMTYPE);
  553. vogltextattr= (struct TextAttr *)  AllocMem((LONG) sizeof(struct TextAttr),MEMTYPE);
  554.  
  555. /* optionally set up double buffering via AMIGA_backbuffer() */
  556. if(scrbufmode == DBLBUFMODE) AMIGA_backbuffer();
  557.  
  558. /* initial rawkey buffer allocation */
  559. if(!rawkeybuf) {
  560.     qtyrawkeybuf= RAWKEYBUF;
  561.     rawkeybuf   = (char *) AllocMem(qtyrawkeybuf,MEMTYPE);
  562.  
  563.     if(!rawkeybuf) {    /* terminate on no buffer */
  564.         AMIGA_exit();
  565.         printf("***warning*** unable to allocate a %ld byte buffer for rawkeys\n",
  566.           qtyrawkeybuf);
  567.         goto initproblem;
  568.         }
  569.     }
  570.  
  571. /* allocate an InputEvent */
  572. voglievent= (struct InputEvent *) AllocMem(sizeof(struct InputEvent),MEMTYPE);
  573. if(!voglievent) {
  574.     AMIGA_exit();
  575.     printf("***warning*** unable to allocate an InputEvent\n");
  576.     goto initproblem;
  577.     }
  578.  
  579. /* initialize vogl screensize variables*/
  580. vdevice.sizeSx= scrwidth  - 1;        /* x: upper right corner    */
  581. vdevice.sizeSy= scrheight - 1;        /* y: upper right corner    */
  582. vdevice.depth = scrdepth;            /* z: qty bitplanes            */
  583. vdevice.sizeX = vdevice.sizeY= (scrheight < scrwidth)? scrheight : scrwidth;
  584.  
  585. /* initialize the colormap */
  586. AMIGA_mapcolor(0, 0, 0, 0);            /* black                    */
  587. AMIGA_mapcolor(1,15, 0, 0);            /* red                        */
  588. if(scrdepth >= 2) {
  589.     AMIGA_mapcolor(2, 0,15, 0);        /* green                    */
  590.     AMIGA_mapcolor(3,15,15, 0);        /* yellow                    */
  591.     if(scrdepth >= 3) {
  592.         int icolor;
  593.         AMIGA_mapcolor(4, 0, 0,15);    /* blue                        */
  594.         AMIGA_mapcolor(5,15, 0,15);    /* magenta                    */
  595.         AMIGA_mapcolor(6, 0,15,15);    /* cyan                        */
  596.         AMIGA_mapcolor(7,15,15,15);    /* white                    */
  597.  
  598.         /* make the rest, if any, black */
  599.         for(icolor= 8; icolor < (1<<scrdepth); ++icolor)
  600.           AMIGA_mapcolor(icolor,0,0,0);
  601.         }
  602.     }
  603.  
  604. return 1;
  605.  
  606. initproblem:
  607. return(0);
  608. }
  609.  
  610. /* -------------------------------------------------------------------------- */
  611.  
  612. /* makeBitMap: this function sets up one bitmap.  Double buffering, of
  613.  * course, requires two bitmaps.
  614.  */
  615. static struct BitMap *makeBitMap(void)
  616. {
  617. int            idepth;
  618. struct BitMap *bitmap=NULL;
  619.  
  620. /* allocate BitMap itself */
  621. bitmap= AllocMem((LONG) sizeof(struct BitMap),MEMTYPE);
  622.  
  623. if(bitmap) {
  624.     InitBitMap(bitmap,(LONG) scrdepth,(LONG) scrwidth,(LONG) scrheight);
  625.  
  626.     for(idepth= 0; idepth < scrdepth; ++idepth) {
  627.         bitmap->Planes[idepth]= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  628.         if(!bitmap->Planes[idepth]) {    /* unable to get enough memory */
  629.             for(--idepth; idepth >= 0; --idepth)
  630.               FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  631.             FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  632.             break;
  633.             }
  634.         BltClear(bitmap->Planes[idepth],(scrwidth>>3)*scrheight,1);
  635.         }
  636.     }
  637.  
  638. return bitmap;
  639. }
  640.  
  641. /* -------------------------------------------------------------------------- */
  642.  
  643. /* freeBitMap: this function frees up memory used by a BitMap */
  644. static int freeBitMap(struct BitMap *bitmap)
  645. {
  646. int idepth;
  647.  
  648.     for(idepth= scrdepth-1; idepth >= 0; --idepth) {
  649.         FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  650.     }
  651.     FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  652.     return(0);
  653. }
  654.  
  655. /* -------------------------------------------------------------------------- */
  656.  
  657. /* AMIGA_exit: cleans up before returning the window to normal
  658.  *  Note: I've designed this driver so that it can be re-opened.
  659.  */
  660. static int AMIGA_exit(void)
  661. {
  662. FontList *prvfontlist;
  663.  
  664. /* clear back screen */
  665. if(voglscreen) SetRast(&(voglscreen->RastPort),(unsigned long) 0);
  666.  
  667. /* close open Fonts and clean up memory use */
  668. while(fontlisthd) {
  669.     CloseFont(fontlisthd->textfont);
  670.     free((char *) fontlisthd->fontspec);
  671.     fontlisthd->textfont= NULL;
  672.     fontlisthd->fontspec= NULL;
  673.     prvfontlist         = fontlisthd;
  674.     fontlisthd          = fontlisthd->nxt;
  675.     free((char *) prvfontlist);
  676.     }
  677. fontlisthd= NULL;
  678.  
  679. /* free up rawkey buffer */
  680. if(voglievent) FreeMem(voglievent,sizeof(struct InputEvent));
  681. if(rawkeybuf)  FreeMem(rawkeybuf,qtyrawkeybuf);
  682.  
  683. if(vogltextattr->ta_Name) {
  684.     int slen;
  685.     slen= strlen((char *) vogltextattr->ta_Name);
  686.     if(slen & 1) ++slen;
  687.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  688.     vogltextattr->ta_Name= NULL;
  689.     }
  690. if(vogltextattr) FreeMem(vogltextattr,sizeof(struct TextAttr));
  691. if(voglstring)   FreeMem(voglstring,MAXSTRING*sizeof(UBYTE));
  692. if(voglitext)    FreeMem(voglitext,sizeof(struct IntuiText));
  693. vogltextattr= NULL;
  694. voglstring  = NULL;
  695. voglitext   = NULL;
  696.  
  697. if(voglplaneptr) {
  698.     FreeRaster(voglplaneptr,scrwidth,scrheight);
  699.     voglplaneptr= NULL;
  700.     }
  701.  
  702. if(vogltmpras) {
  703.     FreeMem(vogltmpras,sizeof(struct TmpRas));
  704.     }
  705. voglrastport->TmpRas= vogltmpras= NULL;
  706.  
  707. if(voglrastport->AreaInfo) {
  708.     FreeMem(voglrastport->AreaInfo,sizeof(struct AreaInfo));
  709.     }
  710. voglrastport->AreaInfo= NULL;
  711.  
  712. if(voglareaBuffer) {
  713.     FreeMem(voglareaBuffer,5*MAXVRTX);
  714.     }
  715. voglareaBuffer= NULL;
  716.  
  717. if(voglwindow) {
  718.     CloseWindow(voglwindow);
  719.     }
  720. voglwindow= NULL;
  721.  
  722. if(voglscreen) {
  723.     CloseScreen(voglscreen);
  724.     }
  725. voglscreen= NULL;
  726.  
  727. /* free up BitMaps */
  728. if(voglback)  freeBitMap(voglback);
  729. if(voglfront) freeBitMap(voglfront);
  730. voglfront= voglback= NULL;
  731.  
  732. /* close down Libraries */
  733. if(ConsoleDevice) {
  734.     CloseDevice((struct IORequest *) vogl_cd_ioreq);
  735.     }
  736. ConsoleDevice= NULL;
  737. if(DiskfontBase) {
  738.     CloseLibrary((struct Library *) DiskfontBase);
  739.     }
  740. DiskfontBase= NULL;
  741. if(GfxBase) {
  742.     CloseLibrary((struct Library *) GfxBase);
  743.     }
  744. GfxBase= NULL;
  745. if(IntuitionBase) {
  746.     CloseLibrary((struct Library *) IntuitionBase);
  747.     }
  748. IntuitionBase= NULL;
  749.  
  750. /* free up memory for Console Device */
  751. if(vogl_cd_ioreq) {
  752.     FreeMem(vogl_cd_ioreq,sizeof(struct IOStdReq));
  753.     }
  754. vogl_cd_ioreq= NULL;
  755.  
  756. return(0);
  757. }
  758.  
  759. /* -------------------------------------------------------------------------- */
  760.  
  761. /* AMIGA_draw: draws a line from the current graphics position to (x, y) */
  762. static int AMIGA_draw(  int x,  int y)
  763. {
  764.     Move(voglrastport,vdevice.cpVx,vdevice.sizeSy - vdevice.cpVy);
  765.     Draw(voglrastport,x,vdevice.sizeSy - y);
  766.     return(0);
  767. }
  768.  
  769. /* -------------------------------------------------------------------------- */
  770.  
  771. /* AMIGA_getkey: grab a character from the keyboard
  772.  *  (empties voglkeybuf)
  773.  */
  774. static int AMIGA_getkey(void)
  775. {
  776. int   key;
  777. int   mb,wx,wy;        /* to make AMIGA_locator happy */
  778. int   newikeybgn;
  779. ULONG signals;
  780.  
  781. newikeybgn= ikeybgn + 1;
  782. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  783.  
  784. if(newikeybgn != ikeyend) {
  785.     /* update ikeybgn index and get key from voglkeybuf */
  786.     ikeybgn= newikeybgn;
  787.     key    = voglkeybuf[ikeybgn];
  788.     }
  789.  
  790. else {
  791.  
  792.     /* block until a key is hit */
  793.     do {
  794.         signals= Wait(1L << voglwindow->UserPort->mp_SigBit);
  795.         if(signals & (1L << voglwindow->UserPort->mp_SigBit)) {
  796.             mb= AMIGA_locator(&wx,&wy);
  797.             }
  798.         } while(newikeybgn == ikeyend);
  799.  
  800.     /* update ikeybgn index and get key from voglkeybuf */
  801.     ikeybgn= newikeybgn;
  802.     key    = voglkeybuf[ikeybgn];
  803.     }
  804.  
  805. return key;
  806. }
  807.  
  808. /* -------------------------------------------------------------------------- */
  809.  
  810. /* AMIGA_checkkey: Check if a keyboard key has been hit. If so return it
  811.  *  Otherwise, return 0.  Note: this function does actually read the
  812.  *  key (ie. remove it from the buffer) if one has been hit.  That's
  813.  *  the way the qread/qtest functions like it.
  814.  */
  815. static int AMIGA_checkkey(void)
  816. {
  817. int key;
  818. int mb,wx,wy;        /* to make AMIGA_locator happy */
  819. int newikeybgn;
  820.  
  821.  
  822. /* fill up rawkeybuf with any pending key hits */
  823. mb = AMIGA_locator(&wx,&wy);
  824.  
  825. newikeybgn= ikeybgn + 1;
  826. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  827. if(newikeybgn != ikeyend) {
  828.     ikeybgn= newikeybgn;
  829.     key    = voglkeybuf[ikeybgn];
  830.     }
  831. else key= 0;
  832.  
  833. return key;
  834. }
  835.  
  836. /* -------------------------------------------------------------------------- */
  837.  
  838. /* AMIGA_handlekey: this function handles RAWKEYs  (fills up voglkeybuf)
  839.  *     voglkeybuf                                      voglkeybuf
  840.  *   |uuuddddddduuuuu|    u=unused  d=data            |ddddduuuuuuudd|
  841.  *      ^       ^                                           ^     ^
  842.  *   ikeybgn    ikeyend   (always point to unused)     ikeyend    ikeybgn
  843.  */
  844. static void AMIGA_handlekey(struct IntuiMessage *Imsg)
  845. {
  846. int      dbl=0;
  847. LONG     numchars;
  848. unsigned newikeyend;
  849.  
  850. /* convert rawkey message into a vanilla key */
  851. do {
  852.     voglievent->ie_Class           = IECLASS_RAWKEY;
  853.     voglievent->ie_Code            = Imsg->Code;
  854.     voglievent->ie_Qualifier       = Imsg->Qualifier;
  855.     voglievent->ie_position.ie_addr= *((APTR*) Imsg->IAddress);
  856.  
  857.     numchars= RawKeyConvert(voglievent,(STRPTR) rawkeybuf,qtyrawkeybuf-1,NULL);
  858.     dbl    = numchars == -1 && !rawkeybuf[0];
  859.  
  860.     if(dbl) {    /* double size of rawkeybuf to enable conversion */
  861.         FreeMem(rawkeybuf,qtyrawkeybuf);
  862.         qtyrawkeybuf<<= 1;
  863.         rawkeybuf     = AllocMem(qtyrawkeybuf,MEMTYPE);
  864.         if(!rawkeybuf) {    /* unable to double rawkey buffer! */
  865.             qtyrawkeybuf= 0;
  866.             AMIGA_exit();
  867.             }
  868.         }
  869.     } while(dbl);
  870.  
  871. /* numchars contains the number of characters placed within the rawkeybuf.
  872.  * Key up events and key sequences which do not generate any data for the
  873.  * program (deadkeys, already intercepted sequences, etc) will return zero.
  874.  *
  875.  * Special keys (HELP, cursor keys, FKeys, etc) return multiple characters
  876.  * that have to be parsed below.
  877.  *
  878.  * There are a number of qualifiers available, most of which are currently
  879.  * being ignored by this vogl-amiga driver.  However, for reference purposes:
  880.  *
  881.  * (Imsg->Code & 0x80)? key-up : key-down
  882.  * 
  883.  *  Imsg->Qualifier can be "anded" with
  884.  * 
  885.  *    IEQUALIFIER_CAPSLOCK       IEQUALIFIER_LSHIFT         IEQUALIFIER_RBUTTON       
  886.  *    IEQUALIFIER_CONTROL        IEQUALIFIER_MIDBUTTON      IEQUALIFIER_RCOMMAND      
  887.  *    IEQUALIFIER_INTERRUPT      IEQUALIFIER_MULTIBROADCAST IEQUALIFIER_RELATIVEMOUSE 
  888.  *    IEQUALIFIER_LALT           IEQUALIFIER_NUMERICPAD     IEQUALIFIER_REPEAT        
  889.  *    IEQUALIFIER_LCOMMAND       IEQUALIFIER_RALT           IEQUALIFIER_RSHIFT        
  890.  *    IEQUALIFIER_LEFTBUTTON     
  891.  */
  892.  
  893. /* key is pressed down */
  894. if(!(Imsg->Code & 0x80)) {
  895.  
  896.     /* handlekey only accepts alphameric (assumed to be caps), numeric, and unshifted
  897.      * punctuation.  Report sequences (function keys, help, cursor keys, etc) are
  898.      * ignored!
  899.      */
  900.     newikeyend= ikeyend + 1;
  901.     if(newikeyend >= KEYBUF) newikeyend= 0;
  902.     
  903.     if(newikeyend != ikeybgn && rawkeybuf[0] != 0x9b) {    /* 0x9b is a report sequence */
  904.         if     (islower(rawkeybuf[0]))   rawkeybuf[0]= toupper(rawkeybuf[0]);    /* lower -> upper    */
  905.         else if(rawkeybuf[0] == '\177')  rawkeybuf[0]= '\020';                    /* DEL key mapping    */
  906.         voglkeybuf[ikeyend]= rawkeybuf[0];
  907.         ikeyend            = newikeyend;
  908.         }
  909.     }
  910.  
  911. }
  912.  
  913. /* --------------------------------------------------------------------- */
  914.  
  915. /* AMIGA_locator:
  916.  *    return the window location of the cursor,
  917.  *  plus which mouse button, if any, has been pressed.
  918.  *
  919.  * Bit   0     1      2    is 1 when button is pressed down
  920.  *     |left|middle|right| is 0 when button is released
  921.  */
  922. static int AMIGA_locator(  int *wx,  int *wy)
  923. {
  924. int                  mb  = 0;
  925. struct Message      *Mmsg= NULL;
  926. struct IntuiMessage *Imsg= NULL;
  927.  
  928. /* get current mouse position */
  929. *wx= voglwindow->MouseX;
  930. *wy= vdevice.sizeSy - voglwindow->MouseY;
  931.  
  932. while(Mmsg= GetMsg(voglwindow->UserPort)) {
  933.     Imsg= (struct IntuiMessage *) Mmsg;
  934.  
  935.     switch(Imsg->Class) {
  936.  
  937.     case IDCMP_MOUSEBUTTONS:
  938.  
  939.         switch(Imsg->Code) {
  940.  
  941.         case SELECTDOWN:    /* left   mouse pressed        */
  942.             mb|= 01;
  943.             break;
  944.  
  945.         case SELECTUP:        /* left   mouse released    */
  946.             mb&= ~01;
  947.             break;
  948.  
  949.         case MIDDLEDOWN:    /* middle mouse pressed        */
  950.             mb|= 02;
  951.             break;
  952.  
  953.         case MIDDLEUP:        /* middle mouse released    */
  954.             mb&= ~02;
  955.             break;
  956.  
  957.         case MENUDOWN:        /* right  mouse pressed        */
  958.             mb|= 04;
  959.             break;
  960.  
  961.         case MENUUP:        /* right  mouse released    */
  962.             mb&= ~04;
  963.             break;
  964.  
  965.         default:
  966.             break;
  967.             }
  968.         break;
  969.  
  970.     case IDCMP_RAWKEY:        /* a key was hit/released    */
  971.         AMIGA_handlekey(Imsg);
  972.         break;
  973.  
  974.     default:                /* unsupported Intuimessage    */
  975.         break;
  976.         }
  977.  
  978.     ReplyMsg(Mmsg);
  979.     }
  980.  
  981. return mb;
  982. }
  983.  
  984. /* -------------------------------------------------------------------------- */
  985.  
  986. /* AMIGA_clear: Clear the screen to current color */
  987. static int AMIGA_clear(void)
  988. {
  989.     SetRast(voglrastport,(unsigned long) currcolor);
  990.     return(0);
  991. }
  992.  
  993. /* -------------------------------------------------------------------------- */
  994.  
  995. /* AMIGA_color: set the current drawing color index */
  996. static int AMIGA_color(int icolor)
  997. {
  998.     currcolor= icolor;                /* used by string/char rendering */
  999.     SetAPen(voglrastport,icolor);
  1000.     return(0);
  1001. }
  1002.  
  1003. /* -------------------------------------------------------------------------- */
  1004.  
  1005. /* AMIGA_mapcolor: change index icolor in the color map to the appropriate
  1006.  *  r, g, b, value.
  1007.  */
  1008. static int AMIGA_mapcolor(  int icolor,  int r,  int g,  int b)
  1009. {
  1010. if(icolor >= (1<<scrdepth)) {
  1011.     return(0);
  1012.     }
  1013.  
  1014. SetRGB4(&voglscreen->ViewPort,
  1015.   (long)          icolor,
  1016.   (unsigned long) r,
  1017.   (unsigned long) g,
  1018.   (unsigned long) b);
  1019.  
  1020.     return(0);
  1021. }
  1022.  
  1023. /* -------------------------------------------------------------------------- */
  1024.  
  1025. /* AMIGA_font: Set up a hardware font. Return 1 on success 0 otherwise
  1026.  *  I have come up with a little convention for the fontspec:
  1027.  *    fontname;height[;{BEIPU}]
  1028.  *   B == bold
  1029.  *   E == extended
  1030.  *   I == italic
  1031.  *   P == plain (default)
  1032.  *   U == underlined
  1033.  *
  1034.  *  Returns: 0=failure-to-open
  1035.  *           1=successful font open
  1036.  */
  1037. static int AMIGA_font(char *fontspec)
  1038. {
  1039. char             type='P';        /* font spec type            */
  1040. char            *fsh;            /* ptr to font spec height    */
  1041. char            *fst;            /* ptr to font spec type    */
  1042. // int              h;                /* height                    */
  1043. int              slen;            /* length of fontname        */
  1044. FontList        *fontlist    = NULL;
  1045. struct TextFont *vogltextfont= NULL;
  1046. static FontList *oldfontlist = NULL;
  1047.  
  1048. /* check over FontList for fontspec */
  1049. for(fontlist= fontlisthd; fontlist; fontlist= fontlist->nxt) {
  1050.  
  1051.     if(!strcmp(fontlist->fontspec,fontspec)) {
  1052.     
  1053.         if(fontlist == oldfontlist) {    /* font unchanged! */
  1054.             return(0);
  1055.             }
  1056.  
  1057.         vdevice.hheight= fontlist->textfont->tf_YSize;
  1058.         vdevice.hwidth = fontlist->textfont->tf_XSize;
  1059.     
  1060.         /* set the font */
  1061.         SetFont(voglrastport,fontlist->textfont);
  1062.         oldfontlist= fontlist;
  1063.         return 1;
  1064.         }
  1065.     }
  1066.  
  1067. /* get font-separator pointers */
  1068. fsh                   = strchr(fontspec,FONTSEP);    /* nominal font height        */
  1069. fst                   = strchr(fsh+1,FONTSEP);        /* type of font                */
  1070. vogltextattr->ta_Style= (UBYTE) 0;                    /* default style == plain    */
  1071. vogltextattr->ta_Flags= (UBYTE) 0;                    /* default style == plain    */
  1072.  
  1073. if(fsh) {
  1074.     sscanf(fsh+1,"%hu",&vogltextattr->ta_YSize);
  1075.     *fsh= '\0';
  1076.  
  1077.     if(fst) {
  1078.         for(++fst; *fst; ++fst) switch(*fst) {
  1079.  
  1080.         case 'B':    /* bold */
  1081.         case 'b':
  1082.             vogltextattr->ta_Style|= FSF_BOLD;
  1083.             break;
  1084.  
  1085.         case 'E':    /* extended (extra wide) */
  1086.         case 'e':
  1087.             vogltextattr->ta_Style|= FSF_EXTENDED;
  1088.             break;
  1089.  
  1090.         case 'I':    /* italic */
  1091.         case 'i':
  1092.             vogltextattr->ta_Style|= FSF_ITALIC;
  1093.             break;
  1094.  
  1095.         case 'P':    /* plain */
  1096.         case 'p':
  1097.             break;
  1098.  
  1099.         case 'U':    /* underlined */
  1100.         case 'u':
  1101.             vogltextattr->ta_Style|= FSF_UNDERLINED;
  1102.             break;
  1103.  
  1104.         default:    /* ignored */
  1105.             break;
  1106.             }
  1107.         }
  1108.     }
  1109. else vogltextattr->ta_YSize= 11L;            /* default height == 11 pts    */
  1110.  
  1111. /* free up old ta_Name */
  1112. if(vogltextattr->ta_Name) {
  1113.     slen= strlen((char *) vogltextattr->ta_Name);
  1114.     if(slen & 1) ++slen;
  1115.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  1116.     vogltextattr->ta_Name= NULL;
  1117.     }
  1118. slen= strlen(fontspec) + 6;
  1119. if(slen & 1) ++slen;
  1120. vogltextattr->ta_Name= (STRPTR) AllocMem((LONG) slen*sizeof(char),MEMTYPE);
  1121. sprintf((char *) vogltextattr->ta_Name,"%s.font",fontspec);
  1122.  
  1123. if(fsh) *fsh= FONTSEP;                            /* restore *fsh            */
  1124.  
  1125.  
  1126. /* attempt to open requested font */
  1127. vogltextfont= OpenDiskFont(vogltextattr);        /* open the font        */
  1128. if(vogltextfont) {
  1129.     SetFont(voglrastport,vogltextfont);            /* set the font            */
  1130.  
  1131.     /* set up FontList */
  1132.     head_link(FontList,fontlisthd,"FontList");
  1133.     stralloc(fontlisthd->fontspec,fontspec,"fontspec");
  1134.     fontlisthd->textfont= vogltextfont;
  1135.     oldfontlist         = fontlisthd;
  1136.     vdevice.hheight     = fontlisthd->textfont->tf_YSize;
  1137.     vdevice.hwidth      = fontlisthd->textfont->tf_XSize;
  1138.     }
  1139. else {    /* failure to open requested font */
  1140.     vdevice.hheight= 0;
  1141.     vdevice.hwidth = 0;
  1142.     return 0;
  1143.     }
  1144.  
  1145. return 1;
  1146. }
  1147.  
  1148. /* -------------------------------------------------------------------------- */
  1149.  
  1150. /* AMIGA_char: outputs one char */
  1151. static int AMIGA_char(char c)
  1152. {
  1153.     char s[2];
  1154.  
  1155.     s[0]= c;
  1156.     s[1]= '\0';
  1157.     AMIGA_string(s);
  1158.     return(0);
  1159. }
  1160.  
  1161. /* -------------------------------------------------------------------------- */
  1162.  
  1163. /* AMIGA_string: Display a string at the current drawing position */
  1164. static int AMIGA_string(char *s)
  1165. {
  1166. /* set up the IntuiText */
  1167. voglitext->FrontPen = (UBYTE) currcolor;    /* set text's foreground color        */
  1168. voglitext->BackPen  = (UBYTE) 0;            /* background color ignored            */
  1169. voglitext->DrawMode = JAM1;                    /* just use fgd color                */
  1170.  
  1171. voglitext->LeftEdge = vdevice.cpVx;            /* set x position                    */
  1172. /* set y position            */
  1173. voglitext->TopEdge  = (short)(vdevice.sizeSy - vdevice.cpVy - vdevice.hheight);
  1174.  
  1175. voglitext->ITextFont= NULL;                    /* use default font                    */
  1176. strcpy((char *) voglstring,s);                /* copy user's string to voglstring    */
  1177. voglitext->IText    = voglstring;            /* print out voglstring                */
  1178. voglitext->NextText = NULL;                    /* no next text                        */
  1179.  
  1180. PrintIText(voglrastport,voglitext,0L,0L);    /* use printIText to render            */
  1181.  
  1182.     return(0);
  1183.  
  1184. }
  1185.  
  1186. /* -------------------------------------------------------------------------- */
  1187.  
  1188. /* AMIGA_fill: fill a polygon */
  1189. static int AMIGA_fill(  int  n,  int *x,  int *y)
  1190. {
  1191. int ifill;
  1192. // int result;
  1193.  
  1194. if(AreaMove(voglrastport,(long) x[0],(long) vdevice.sizeSy - y[0]) < 0) {
  1195.     printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1196.     return(0);
  1197.     }
  1198.  
  1199. for(ifill= 1; ifill < n; ++ifill) {
  1200.     if(AreaDraw(voglrastport,(long) x[ifill],(long) vdevice.sizeSy - y[ifill]) < 0) {
  1201.         printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1202.         return(0);
  1203.         }
  1204.     }
  1205.  
  1206. AreaEnd(voglrastport);
  1207.  
  1208. vdevice.cpVx = x[n - 1];
  1209. vdevice.cpVy = y[n - 1];
  1210.  
  1211.     return(0);
  1212. }
  1213.  
  1214. /* -------------------------------------------------------------------------- */
  1215.  
  1216. /* AMIGA_backbuffer: draw in back buffer, display front
  1217.  *  Returns 0=success
  1218.  *         -1=failure
  1219.  */
  1220. static int AMIGA_backbuffer(void)
  1221. {
  1222. if(scrbufmode == SNGLBUFMODE) {    /* begin double buffer mode */
  1223.     scrbufmode                 = DBLBUFMODE;
  1224.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1225.     voglscreen->RastPort.Flags = DBUFFER;
  1226.     }
  1227.  
  1228. if(voglback && voglscreen->RastPort.BitMap != voglback) {
  1229.     MakeScreen(voglscreen);    /* make screen's new copper list            */
  1230.     RethinkDisplay();        /* combine copper lists into single View    */
  1231.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1232.     voglwindow->RPort->BitMap  = voglback;
  1233.     }
  1234.  
  1235. return 0;
  1236. }
  1237.  
  1238. /* -------------------------------------------------------------------------- */
  1239.  
  1240. /* AMIGA_swapbuffer: swap the front and back buffers */
  1241. static int AMIGA_swapbuffer(void)
  1242. {
  1243. struct BitMap *voglswap;
  1244.  
  1245. if(!voglback || scrbufmode != DBLBUFMODE) {
  1246.     return 0;
  1247.     }
  1248.  
  1249. /* display back buffer */
  1250. MakeScreen(voglscreen);    /* make screen's new copper list            */
  1251. RethinkDisplay();        /* combine copper lists into single View    */
  1252.  
  1253. /* swap front and back BitMap buffers */
  1254. voglswap                   = voglfront;
  1255. voglfront                  = voglback;
  1256. voglback                   = voglswap;
  1257. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1258. voglwindow->RPort->BitMap  = voglback;
  1259.  
  1260. return 0;
  1261. }
  1262.  
  1263. /* -------------------------------------------------------------------------- */
  1264.  
  1265. /* AMIGA_frontbuffer: draw in the front buffer */
  1266. static int AMIGA_frontbuffer(void)
  1267. {
  1268.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglfront;
  1269.     voglwindow->RPort->BitMap  = voglfront;
  1270.     return(0);
  1271. }
  1272.  
  1273. /* --------------------------------------------------------------------------
  1274.  * _AMIGA_devcpy
  1275.  *
  1276.  *    copy the amiga device into vdevice.dev.
  1277.  */
  1278. void _AMIGA_devcpy(void)
  1279. {
  1280. vdevice.dev= amigadev;
  1281. }
  1282.  
  1283. /* ==========================================================================
  1284.  * Source Code:
  1285.  *  The test code here exercises the amiga driver by itself and is not
  1286.  *  expected to be the "usual" way of using it.  The usual way is via
  1287.  *  standard vogl methods.
  1288.  */
  1289.  
  1290. /* --------------------------------------------------------------------- */
  1291.  
  1292. /* DT_title: this function sets up the window's title */
  1293. void DT_title(char *buf)
  1294. {
  1295. static char titlebuf[RAWKEYBUF];
  1296.  
  1297. strcpy(titlebuf,buf);
  1298. vdevice.wintitle= titlebuf;
  1299. }
  1300.  
  1301. /* --------------------------------------------------------------------- */
  1302.  
  1303. #ifdef SASC
  1304. void __regargs __checkabort (void)
  1305. {
  1306. /* empty */
  1307. }
  1308. #endif
  1309.  
  1310. /* --------------------------------------------------------------------- */
  1311.  
  1312.